package com.itheima.stock.service.imp;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.stock.entity.*;
import com.itheima.stock.mapper.*;
import com.itheima.stock.properties.MarketProperties;
import com.itheima.stock.response.PageResult;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.*;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author 李智勇
 * @data 2025/10/21 21:12
 */

@Service
public class StockServiceImpl implements StockService {
    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    private final StockBlockRtInfoMapper stickBlockRtInfoMapper;
    private final StockMarketIndexInfoMapper marketIndexInfoMapper;
    private final StockMarketLogPriceMapper marketLogPriceMapper;
    private final StockBusinessMapper stockBusinessMapper;
    private final MarketProperties marketProperties;

    public StockServiceImpl(StockBusinessMapper stockBusinessMapper, MarketProperties marketProperties, StockBlockRtInfoMapper stickBlockRtInfoMapper, StockMarketIndexInfoMapper marketIndexInfoMapper, StockMarketLogPriceMapper marketLogPriceMapper) {
        this.stockBusinessMapper = stockBusinessMapper;
        this.marketProperties = marketProperties;
        this.stickBlockRtInfoMapper = stickBlockRtInfoMapper;
        this.marketIndexInfoMapper = marketIndexInfoMapper;
        this.marketLogPriceMapper = marketLogPriceMapper;
    }


    @Override
    public StockUpDownVO<InfoVO> stickUpDown() {
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        last = LocalDateTime.parse("2022-01-06 09:55:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<InfoVO> voList = stockRtInfoMapper.selectStockUpDown(last);
        List<String> ranges = new ArrayList<>(Arrays.asList("-10~-7", "-7~-5", "-5~-3", "-3~0", "0~3", "3~5", "5~7", "7~10"));
        List<InfoVO> newArrayList = new ArrayList<>();
        ranges.forEach(range -> {
            voList.forEach(vo -> {
                if (range.equals(vo.getTitle())){
                    newArrayList.add(vo);
                }
            });
        });
        return StockUpDownVO.<InfoVO>builder()
                .infos(newArrayList)
                .time(last.toString())
                .build();
    }

    @Override
    public TradeAmtVO<OptionVO> tradeAmt() {
        LocalDateTime t = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        LocalDateTime t_open = DateTimeUtil.getOpenDate(t);
        LocalDateTime t_close = DateTimeUtil.getCloseDate(t);
        LocalDateTime t_1 = DateTimeUtil.getPreviousTradingDay(t);
        LocalDateTime t_1_open = DateTimeUtil.getOpenDate(t_1);
        LocalDateTime t_1_close = DateTimeUtil.getCloseDate(t_1);
         t_open = LocalDateTime.parse("2021-12-28 09:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         t_close = LocalDateTime.parse("2021-12-28 14:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         t_1_open = LocalDateTime.parse("2021-12-27 09:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         t_1_close = LocalDateTime.parse("2021-12-27 14:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<String> ids = marketProperties.getInner();
        List<OptionVO> list = marketIndexInfoMapper.selectTradeCount(t_1_open,t_close,ids);
        LocalDate tDate = t_open.toLocalDate();
        LocalDate t_1Date = t_1_open.toLocalDate();
        List<OptionVO> tlist = list.stream().filter(vo -> {
            LocalDateTime parse = LocalDateTime.parse(vo.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDate targetDate = parse.toLocalDate();
            return targetDate.isEqual(tDate);
        }).toList();
        List<OptionVO> t_1list = list.stream().filter(vo -> {
            LocalDateTime parse = LocalDateTime.parse(vo.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDate targetDate = parse.toLocalDate();
            return targetDate.isEqual(t_1Date);
        }).toList();
        return TradeAmtVO.<OptionVO>builder()
                .voList(tlist)
                .yesVolList(t_1list)
                .build();
    }

    @Override
    public UpDownVO<OptionVO> upDown() {
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        LocalDateTime begin = LocalDateTime.parse("2022-01-06 09:25:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime end = LocalDateTime.parse("2022-01-06 14:25:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<OptionVO> upList = stockRtInfoMapper.selectUpOrDown(begin,end,true);
        List<OptionVO> downList = stockRtInfoMapper.selectUpOrDown(begin,end,false);
        return UpDownVO.<OptionVO>builder()
                .upList(upList)
                .downList(downList)
                .build();
    }

    @Override
    public PageResult<MoreVO> more(Integer page, Integer pageSize) {
        LocalDateTime last1 = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        final LocalDateTime last = LocalDateTime.parse("2021-12-30 09:32:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Page<MoreVO> result = PageHelper.startPage(page,pageSize).doSelectPage(() -> {
                    List<MoreVO> voList = stockRtInfoMapper.selecMore(last);
                });
        return PageResult.<MoreVO>builder()
                .size(result.size())
                .totalRows(result.getTotal())
                .totalPages(result.getPages())
                .pageNum(result.getPageNum())
                .pageSize(result.getPageSize())
                .rows(result.getResult())
                .build();
    }

    @Override
    public List<IncreaseVO> stockIncrease() {
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        last = LocalDateTime.parse("2021-12-30 09:32:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<StockRtInfo> stockRtInfoList = stockRtInfoMapper.selectByDateTime(last);
        List<IncreaseVO> result = new ArrayList<>();
        stockRtInfoList.stream().forEach(stock ->{
            IncreaseVO vo = new IncreaseVO();
            vo.setCode(stock.getStockCode());
            vo.setName(stock.getStockName());
            vo.setTradePrice(stock.getCurPrice());
            vo.setTradeAmt(stock.getTradeAmount());
            vo.setPreClosePrice(stock.getPreClosePrice());
            vo.setTradeVol(stock.getTradeVolume());
            vo.setCurDate(stock.getCurTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            BigDecimal increase = (stock.getCurPrice().subtract(stock.getPreClosePrice())).divide(stock.getPreClosePrice(),new MathContext(6)).multiply(new BigDecimal(1.0));
            BigDecimal upDown = stock.getCurPrice().subtract(stock.getPreClosePrice());
            BigDecimal range = (stock.getMaxPrice().subtract(stock.getMinPrice())).divide(stock.getPreClosePrice(),new MathContext(6)).multiply(new BigDecimal(1.0));
            vo.setIncrease( increase);
            vo.setUpDown(upDown);
            vo.setAmplitude(range);
            result.add(vo);
        });
        List<IncreaseVO> list = result.stream().sorted((o1, o2) ->  o2.getIncrease().compareTo(o1.getIncrease())).limit(10).toList();
        return list ;
    }

    @Override
    public List<SectorAllVO> sectorAll() {
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        last = LocalDateTime.parse("2021-12-21 09:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime begin = DateTimeUtil.getOpenDate(last);
        LocalDateTime end = DateTimeUtil.getCloseDate(last);
        List<StockBlockRtInfo> blockRtInfoList = stickBlockRtInfoMapper.selectByDateTimeDesc(begin,end);

        return blockRtInfoList.stream().map(blockRtInfo-> SectorAllVO.builder()
                .code(blockRtInfo.getLabel())
                .name(blockRtInfo.getBlockName())
                .companyNum(blockRtInfo.getCompanyNum())
                .avgPrice(blockRtInfo.getAvgPrice())
                .updownRate(blockRtInfo.getUpdownRate())
                .tradeAmt(blockRtInfo.getTradeAmount())
                .tradeVol(blockRtInfo.getTradeVolume())
                .curDate(blockRtInfo.getCurTime().toString())
                .build()).toList();
    }

    @Override
    public List<InnerMarketVO> innerIndexAll() {
        List<String> ids = marketProperties.getInner();
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        String mockDate = "20211226105600";
        last = LocalDateTime.parse(mockDate, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        List<StockMarketIndexInfo> stockMarketIndexInfoList = marketIndexInfoMapper.selectByIdsAndTime(ids,last);
        List<StockMarketLogPrice> stockMarketLogPriceList = marketLogPriceMapper.selectByIdsAndDate(ids,last.toLocalDate());
        return stockMarketIndexInfoList.stream().map((info)->{
            InnerMarketVO vo = InnerMarketVO.builder().build();
            vo.setCode(info.getMarkId());
            vo.setName(info.getMarkName());
            vo.setCurDate(info.getCurTime().toString());
            vo.setTradeAmt(info.getTradeAccount());
            vo.setTradePrice(info.getCurrentPrice());
            vo.setTradeVol(info.getTradeVolume());
            vo.setUpDown(info.getUpdownRate());
            stockMarketLogPriceList.forEach((logPrice) -> {
                if (info.getMarkId().equals(logPrice.getMarketCode())) {
                    vo.setOpenPrice(logPrice.getOpenPrice());
                    vo.setPreClosePrice(logPrice.getPreClosePrice());
                } else {
                    vo.setOpenPrice(BigDecimal.ZERO);
                    vo.setPreClosePrice(BigDecimal.ZERO);
                }

        });
        return vo;
    }).toList();
}

    @Override
    public List<StockBusiness> getStockBusiness() {

        return stockBusinessMapper.selectAll();
    }
}